package org.zeroes.Components;

import org.zeroes.Events.Callback;
import org.zeroes.Events.Condback;
import org.zeroes.Events.ZSEvent;
import org.zeroes.Events.ZSEventSheet;

import com.zeroes.cons.ZSGameManager;
import com.zeroes.cons.ZSSprite;
import org.zeroes.svg.*;

import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.PathMeasure;

public class ZSBMoveAlongPath extends ZSSpriteBehavior{

	
	private float dest;

	private float diff;

	private float start;
	private Path currPath;
	private boolean ended=false;

	private float  prcntg=0.0f;
	private int dur;
	private int repeats;
	public int ease;
	private int delay;


	private int inc=1;
	private ZSSprite _subj;
	
	public ZSBMoveAlongPath(String name,ZSSprite subject, int delay, int repeats, int _ease){
		super(name,subject);

		this.AddIntegerProperty("*.property.delay", delay);
		this.AddIntegerProperty("*.property.repeats", repeats);
		this.AddIntegerProperty("*.property.ease", _ease);
		this.repeats=repeats;
		this.delay=delay;
		this.ease=_ease;
		this._subj=subject;
		this.on(subject.tag+".AlongPath.run", new Callback(){
			
			public void run(String p, ZSEvent e){
				if(e.loopindex>=0)
				{
					//Log.v("gtrans"," > "+e.loopindex/dur);
					float step=0;
					 int stepLength = 17;
				
					
					 float neededframes=(dur/stepLength);
					 if(FrameRateDependant){
						 	step=diff;
						
							inc=1;
							prcntg=(float)e.loopindex/dur;
							
					 }
					 else
					 {
					 	step=diff/neededframes;
						
						prcntg=inc/neededframes;
						// tb actualizat
						//ended= (destX>startX&&(startX+inc*stepx)>destX)||(destX<startX&&(startX+inc*stepx)<destX) ? true : false;
									
					 }
							
					
					if(!ended){
						//super.onUpdate(stepLength);
						switch(ease){
						case ZSBehavior.LINEAR :
							updateSubjTransform(start+prcntg*inc*step);
						break;
						case ZSBehavior.EASE_IN :
							updateSubjTransform(start+ZSBehavior.cubicin(prcntg)*diff);
						break;	
						case ZSBehavior.EASE_OUT :
							updateSubjTransform(start+ZSBehavior.cubicout(prcntg)*diff);
						break;	
						case ZSBehavior.EASE_IN_OUT :
							updateSubjTransform(start+ZSBehavior.cubicinout(prcntg,dur)*diff);
						break;	
						case ZSBehavior.BACK_IN :
							updateSubjTransform(start+ZSBehavior.backin(prcntg)*diff);
						break;
						case ZSBehavior.BACK_OUT :
							updateSubjTransform(start+ZSBehavior.backout(prcntg)*diff);
						break;
						case ZSBehavior.ELASTIC_IN :
							updateSubjTransform(start+ZSBehavior.elasticin(prcntg,dur/1000)*diff);
						break;
						case ZSBehavior.ELASTIC_OUT :
							updateSubjTransform(start+ZSBehavior.elasticout(prcntg,neededframes)*diff);
							//Log.v("gtrans"," > "+(startY+ZSBehavior.elasticout(100*e.loopindex/dur,dur)*diffY));
							break;
						case ZSBehavior.BOUNCE :
							updateSubjTransform(start+ZSBehavior.bounce(prcntg)*diff);
						break;
						}
						
						
					}
						
					inc++;
					
				

				
				//_subj.setPosition((startX+(float)e.loopindex/dur*diffX), (startY+(float)e.loopindex/dur*diffY));
				}
					else
				{
						inc =1;
						ended=false;
						

						
						updateSubjTransform(0.0f);
					
					String[] items = e.name.split("\\.");
					ZSGameManager.AskMe().events._(items[0]+"."+items[1]+".finished", e);
					
				}
			}
		});
		
		
		this.AddAction("*.action.run", new ZSLogicUnit(){
			
			public void is(ZSComponent c, ZSLUParameters p){
				ZSBMoveAlongPath b =(ZSBMoveAlongPath)c;
				
				ZSSprite target = b.getSpriteProperty("Subject");
				ZSEventSheet E = ZSGameManager.AskMe().events;
				E._(target.tag+".AlongPath.start", null);
				int delay= b.getIntegerProperty("delay");
				int rep= b.getIntegerProperty("repeats");
				ZSSingle<Integer> sd=(ZSSingle<Integer>)p.getParamAtIndex(0);
				ZSSingle<String> pathid=(ZSSingle<String>)p.getParamAtIndex(1);
				//ZSSingle<Integer> _y=(ZSSingle<Integer>)p.getParamAtIndex(2);
				String pid = pathid.getFirst();
				SVGElement path = ZSGameManager.AskMe().forCurrentGame().domparser.getPathById(pid);
				currPath=SVGElement.getPathFromString(path.pathData);
				Matrix m = new Matrix();
				m.setScale(target.getFx(), target.getFy());
				currPath.transform(m);
				float pl = SVGElement.getPathLength(currPath);
				String dir=">";
				if(p.getParamsCount()==2)
					dir=">";
				else
				{
					ZSSingle<String> _dir=(ZSSingle<String>)p.getParamAtIndex(2);
					dir=_dir.getFirst();
				}
				
				if(dir.equals(">")){
				dest=pl;
				

				start=0;

				}
				else
				{
					start=pl;
		

					dest=0;
					
					
				}
				diff=dest-start;
			
				dur=sd.getFirst();
				mainCondition=E.makeCustomDuration(sd.getFirst(),delay,rep,target.tag+".AlongPath.run",new Condback(){
					
					public void is(String n, int idx){
						ZSEvent ev = new ZSEvent(n,null,idx);	
						
						ZSGameManager.AskMe().events._(n, ev);
						
					}
				});
				

				
			}
		});
		
	}
	
	private void updateSubjTransform(float dist){
		
		float[] pos = SVGElement.getPathPositionAtLength(currPath, dist);
		_subj.setPosition(pos[0], pos[1]);
		float _r  = (float) (Math.atan2(pos[2],pos[3])*180/Math.PI);
		//Log.v("gtrans", "Lungime cale : "+pl +" rot "+_r);
		_subj.setRotation(_r);
	}

}
